﻿using System;

namespace Csharp静态类
{
    #region monster管理器
 class MonsterManager
    {
        /*例子*/
        /*Instance----单例模式*/

        //单例的模式---单一的实例---有且只有一个实例，静态能索引到---使用唯一一个静态变量来索引堆中的内容
        //访问速度快
        //把类对象封装成静态对象
        //关闭此类的构造函数
        //用属性去封装静态对象，公开这个属性，以供外部调用
        //这样达到了在静态区中，只有一个变量地址，内容存在堆中
        //这样发挥了静态的优点，又避免了静态的缺点



        //1.不允许别人去实例化出其他实力个体-----（封闭构造函数）

        //2.为了别人方便索引，而且只能访问，使用属性的get方法去封装这个变量
        //3.在外人访问的时候，得先判断一下这个静态变量储存的地址是否为空
        //4.如果为空，就要去堆中开辟空间（使用new 构造函数（）创建一个新对象）
        //5.如果不为空，就直接返回
        //6.这样该类中，其他非静态的成员可以通过中唯一一个去索引
        private static MonsterManager instance = new MonsterManager();//封装了一个静态对象

        //内部
        //属性


        //把对象索引地址从栈中，放到了静态区中
        public static MonsterManager Instance//---->只读
        {
            get 
            {
                if(instance==null)//一旦外部访问地址，先看看堆中有没有内容，如果没有，开一片空间给对方
                {
                    instance = new MonsterManager();//在栈区里面---唯一的实例是在访问的时候创造的
                }
                return instance;//在把新开空间的地址返还出去-----外部调用可以通过instance访问到
            }
        }


        //外面不能访问构造函数-----意味着不能构造对象
        //外部可以通过类名，可以索引到属性

        private MonsterManager() 
        {
            list = new Monster[4];
        }//封闭了本类的构造函数




        public Monster[] list;//列表--->数组不够自动填充
        //列表是非静态的-----储存在堆中
        

        //《--------------动态扩容---------------》
        public  void AddMonster(Monster m) 
        {
            //上车逻辑
            //找到空位才能上来
            for (int i = 0; i < list.Length;i++)
            {
                if (list[i]==null)//如果有空位
                {
                    list[i] = m;//安插进啦
                    return;//只插一个就跳出来

                    //如果没有在上面的流程中return，代表数组满了
                }
            }

            //声明一个新数组，长度是原来的两倍
            Monster[] temp = new Monster[list.Length*2];//--->扩充

            //把原来数组的数据赋值到新数组中
            for (int i=0;i<list.Length;i++)
            {
                temp[i] = list[i];
            }
            list = temp;//数组扩容


            //把新怪物安插进新数组中--！
            for (int i = 0; i < list.Length; i++)
            {
                if (list[i] == null)//如果有空位
                {
                    list[i] = m;//安插进啦
                    return;//只插一个就跳出来

                }
            }

        }
    }
    #endregion


    #region  怪物类
    class Monster
    {
        string name;
        //一旦实例化一个怪物  自动添加到管理类

        //构造函数
        public Monster(string name)
        {
            this.name = name;
            //自动添加到管理类
            MonsterManager.Instance.AddMonster(this);//没有自己的实例----用this关键字
        }

        public void Attack()//攻击函数

        {
            Console.WriteLine("{0}攻击",name);
        }

    }
    #endregion









    class Program
    {
        static void Main(string[] args)
        {
            #region 静态类
            //在声明类的时候加上static修饰的类为静态类
            /*
             * 声明一个怪物类，一旦实例化一个怪物
             * 就自动添加到管理类中去给怪物加一个攻击的行为:在方法中输出一句话
             * 
             * 声明一个怪物管理类(静态)
             * 
             * 实例化10只怪物，让他们统一执行攻击指令
             * 
             */

            for (int i = 0; i < 10; i++)
            {
                new Monster("第"+i+"号哥布林");//直接被接受了，不需要去接受了

            }

            for (int i = 0; i < MonsterManager.Instance.list.Length; i++)
            {

                if (MonsterManager.Instance.list[i] != null)
                {

                    MonsterManager.Instance.list[i].Attack();//调用攻击
                }
            }
            //但是这些static 变量monster不会消失




            #endregion
        }
    }
}
